//this is a module that can generate K
//Last modified by yangjao at 2021/5/11

module K_generator(
    input wire clk,
    input wire rst_n,
    input wire reg_en,
    input wire restart,

    output wire[31:0] data_out
);

parameter K0  = 32'h428a2f98;
parameter K1  = 32'h71374491;
parameter K2  = 32'hb5c0fbcf;
parameter K3  = 32'he9b5dba5;
parameter K4  = 32'h3956c25b;
parameter K5  = 32'h59f111f1;
parameter K6  = 32'h923f82a4;
parameter K7  = 32'hab1c5ed5;
parameter K8  = 32'hd807aa98;
parameter K9  = 32'h12835b01;
parameter K10 = 32'h243185be;
parameter K11 = 32'h550c7dc3;
parameter K12 = 32'h72be5d74;
parameter K13 = 32'h80deb1fe;
parameter K14 = 32'h9bdc06a7;
parameter K15 = 32'hc19bf174;
parameter K16 = 32'he49b69c1;
parameter K17 = 32'hefbe4786;
parameter K18 = 32'h0fc19dc6;
parameter K19 = 32'h240ca1cc;
parameter K20 = 32'h2de92c6f;
parameter K21 = 32'h4a7484aa;
parameter K22 = 32'h5cb0a9dc;
parameter K23 = 32'h76f988da;
parameter K24 = 32'h983e5152;
parameter K25 = 32'ha831c66d;
parameter K26 = 32'hb00327c8;
parameter K27 = 32'hbf597fc7;
parameter K28 = 32'hc6e00bf3;
parameter K29 = 32'hd5a79147;
parameter K30 = 32'h06ca6351;
parameter K31 = 32'h14292967;
parameter K32 = 32'h27b70a85;
parameter K33 = 32'h2e1b2138;
parameter K34 = 32'h4d2c6dfc;
parameter K35 = 32'h53380d13;
parameter K36 = 32'h650a7354;
parameter K37 = 32'h766a0abb;
parameter K38 = 32'h81c2c92e;
parameter K39 = 32'h92722c85;
parameter K40 = 32'ha2bfe8a1;
parameter K41 = 32'ha81a664b;
parameter K42 = 32'hc24b8b70;
parameter K43 = 32'hc76c51a3;
parameter K44 = 32'hd192e819;
parameter K45 = 32'hd6990624;
parameter K46 = 32'hf40e3585;
parameter K47 = 32'h106aa070;
parameter K48 = 32'h19a4c116;
parameter K49 = 32'h1e376c08;
parameter K50 = 32'h2748774c;
parameter K51 = 32'h34b0bcb5;
parameter K52 = 32'h391c0cb3;
parameter K53 = 32'h4ed8aa4a;
parameter K54 = 32'h5b9cca4f;
parameter K55 = 32'h682e6ff3;
parameter K56 = 32'h748f82ee;
parameter K57 = 32'h78a5636f;
parameter K58 = 32'h84c87814;
parameter K59 = 32'h8cc70208;
parameter K60 = 32'h90befffa;
parameter K61 = 32'ha4506ceb;
parameter K62 = 32'hbef9a3f7;
parameter K63 = 32'hc67178f2;

reg[31:0] K [0:63];
reg[5:0] addr;

assign data_out = K[addr];

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        addr <= 6'b0;
    end else if(restart)begin
        addr <= 6'b0;
    end else if(reg_en)begin
        addr <= addr + 1;
    end
end

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        K[0]  <= K0;
        K[1]  <= K1;
        K[2]  <= K2;
        K[3]  <= K3;
        K[4]  <= K4;
        K[5]  <= K5;
        K[6]  <= K6;
        K[7]  <= K7;
        K[8]  <= K8;
        K[9]  <= K9;
        K[10] <= K10;
        K[11] <= K11;
        K[12] <= K12;
        K[13] <= K13;
        K[14] <= K14;
        K[15] <= K15;
        K[16] <= K16;
        K[17] <= K17;
        K[18] <= K18;
        K[19] <= K19;
        K[20] <= K20;
        K[21] <= K21;
        K[22] <= K22;
        K[23] <= K23;
        K[24] <= K24;
        K[25] <= K25;
        K[26] <= K26;
        K[27] <= K27;
        K[28] <= K28;
        K[29] <= K29;
        K[30] <= K30;
        K[31] <= K31;
        K[32] <= K32;
        K[33] <= K33;
        K[34] <= K34;
        K[35] <= K35;
        K[36] <= K36;
        K[37] <= K37;
        K[38] <= K38;
        K[39] <= K39;
        K[40] <= K40;
        K[41] <= K41;
        K[42] <= K42;
        K[43] <= K43;
        K[44] <= K44;
        K[45] <= K45;
        K[46] <= K46;
        K[47] <= K47;
        K[48] <= K48;
        K[49] <= K49;
        K[50] <= K50;
        K[51] <= K51;
        K[52] <= K52;
        K[53] <= K53;
        K[54] <= K54;
        K[55] <= K55;
        K[56] <= K56;
        K[57] <= K57;
        K[58] <= K58;
        K[59] <= K59;
        K[60] <= K60;
        K[61] <= K61;
        K[62] <= K62;
        K[63] <= K63;
    end
end

endmodule
